/*
    created: 2023/4/11
    filename: list.h
    author: 李东霖
    purpose： 带头结点的双链表 代码演示
*/

#ifndef _LIST_H_
#define _LIST_H_

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef int ElemType;
/*


typedef struct DNode
{
    ElemType data;
    struct list* prior;
    struct list* next;

}DNode,*DDLinkList;

//声明操作  

//初始化链表，失败返回NULL成功返回链表的头结点，该结点不存放数据
DNode* InitList1();

//传入指针的地址的初始化方法  
int InitList2(DDLinkList* phead);

//销毁链表
void DestroyList(DDLinkList *phead);

//清空链表  
void ClearList(DDLinkList head);

//获得链表的长度 返回值 -1-链表为NULL >=0-链表长度 
int LengthList(DDLinkList head);

//在链表的第pos个位置插入元素elem 返回值：0-失败 1-成功  
int InsertList(DDLinkList head,unsigned int pos, ElemType *elem);

//在链表头部插入元素elem  返回值：0-失败 1-成功  
int Push_Front(DDLinkList head,ElemType *elem);

//在链表尾部插入元素elem  返回值：0-失败 1-成功  
int Push_Back(DDLinkList head,ElemType *elem);

//打印链表中的全部元素  
void DispList(DDLinkList head);

//删除链表中的第pos个结点 返回值0-失败,pos不合法 1-成功
int DeleteNode(DDLinkList head,unsigned int pos);

//删除链表的头结点 返回值0-失败,链表是空的 1-成功
int Pop_Front(DDLinkList head);

//删除链表的尾结点 返回值0-失败,链表是空的 1-成功
int Pop_Back(DDLinkList head);

//判断链表是否为空 返回值：1-空 0-非空
int Is_Empty(DDLinkList head);

//获取链表第pos个结点，成功返回该结点，失败返回NULL
DNode* LocateNode(DDLinkList head,unsigned int pos);

//查找元素elem在链表中的位置 没有找到该元素返回NULL，否则返回该结点   
DNode* LocateElem(DDLinkList head,ElemType *elem);

//在指定结点pp之前插入元素elem 返回值：0-失败 1-成功
int InsertPriorNode(DNode *pp,ElemType *elem);

//在指定结点pp之后插入元素elem 返回值：0-失败 1-成功
int InsertNextNode(DNode *pp,ElemType *elem);

//删除指定的结点  存在一定的问题  
int DeleteOneNode(DNode *pp);

//归并排序，将传入的两个链表合并为一个新链表(升序)  
int MergeList(DDLinkList La,DDLinkList Lb,DDLinkList Lc);

// 把链表pp结点之后的结点原地逆置（反转），返回值：0-失败；1-成功。
void ReverseList(DNode *pp);
*/
typedef struct DNode
{
  ElemType data;          // 存放结点的数据元素。
  struct DNode *prior,*next;  // 前驱和后继结点的指针。
}DNode,*DLinkList;

// 初始化链表LL，返回值：失败返回NULL，成功返回头结点的地址。
DNode *InitList1();

// 传入指针变量的地址的方法。
// 初始化链表，返回值：0-失败；1-成功。
int InitList2(DLinkList *LL);

// 销毁链表LL。
void DestroyList1(DLinkList LL);

// 销毁链表LL。
// 传入指针的地址的方法。
void DestroyList2(DLinkList *LL);

// C++引用的方法，在Linux下，需要用g++编译。
// 传入指针的地址的方法。
// void DestroyList3(DLinkList &LL);

// 清空链表。
void ClearList(DLinkList LL);                    

// 在链表LL的第ii个位置插入元素ee，返回值：0-失败；1-成功。
int  InsertList(DLinkList LL, unsigned int ii, ElemType *ee);   

// 打印链表中全部的元素。
void DispList(DLinkList LL);                    

// 在链表LL的头部插入元素ee，返回值：0-失败；1-成功。
int  PushFront(DLinkList LL, ElemType *ee);

// 在链表LL的尾部插入元素ee，返回值：0-失败；1-成功。
int  PushBack(DLinkList LL, ElemType *ee);

// 删除链表LL中的第ii个结点，返回值：0-位置ii不合法；1-成功。
int  DeleteNode(DLinkList LL, unsigned int ii);  

// 删除链表LL中第一个结点，返回值：0-位置不合法；1-成功。
int PopFront(DLinkList LL);

// 删除链表LL中最后一个结点，返回值：0-位置不合法；1-成功。
int PopBack(DLinkList LL);

// 求链表的长度，返回值：>=0-表LL结点的个数。
int  LengthList(DLinkList LL);                   

// 判断链表是否为空，返回值：0-非空或失败，1-空。
int IsEmpty(DLinkList LL);

// 获取链表中第ii个结点，成功返回结点的地址，失败返回空。
// 注意，ii可以取值为0，表示头结点。
DNode *LocateNode(DLinkList LL, unsigned int ii);

// 查找元素ee在链表LL中的结点地址，如果没找到返回NULL，否则返回结点的地址。
DNode *LocateElem(DLinkList LL, ElemType *ee);

// 在指定结点pp之后插入元素ee，返回值：0-失败；1-成功。
int InsertNextNode(DNode *pp, ElemType *ee);

// 在指定结点pp之前插入元素ee，返回值：0-失败；1-成功。
int InsertPriorNode(DNode *pp, ElemType *ee);

// 删除指定结点。
int DeleteNode1(DNode *pp);

#endif //!_LIST_H_